HAL NAND initialization and configuration functions migration

The goal of this page is to show how to migrate the initialization sequence using STM32CubeMX2:

  • Open STM32CubeMX2 FMC NAND configuration panel

  • Configure the SW layer HAL.

  • Configure the FMC NAND main features.

  • Configure the advanced FMC NAND features.

  • Configure the FMC NAND security and privilege features if needed.

  • Configure the FMC NAND GPIO pins.

  • Configure the FMC NAND DMA(s) if the application requires to use the FMC NAND in DMA mode.

  • Configure the NVIC if the application requires the FMC NAND to be used in IT mode.

  • Generate the code.

HAL FMC NAND configuration panel

Create a new project with the STM32CubeMX2, then start the initialization and the main configuration.

Project configuration panel

HAL FMC NAND main features configuration

Configure the FMC NAND main features.

FMC NAND main feature configuration

HAL FMC NAND advanced features configuration

Configure the advanced FMC NAND features.

FMC NAND advanced feature configuration

HAL FMC NAND security and privilege features configuration

Configure the FMC NAND security and privilege features if needed.

FMC NAND security and privilege feature configuration

GPIO configuration

Configure GPIO pins.

FMC NAND GPIO configuration

DMA configuration

Configure the DMA for data reception as needed.

FMC NAND DMA configuration

NVIC configuration

Configure the NVIC in case of an interrupt.

FMC NAND NVIC configuration

Generated FMC NAND initialization and de-initialization sequences

The FMC NAND initialization sequence is generated in the mx_fmc_nand_init function in mx_fmc.c file under $YOUR_PROJECT_NAME$/$YOUR_PROJECT_NAME$_SW/generated/STM32Cube_CodeGen.

Related concepts:

STM32CubeMX2 Generated : NAND initialization and De-initialization sequence

Topic

HAL1

HAL2

Initialization and configuration sequence

static void MX_FMC_Init(void)
{
  FMC_NAND_PCC_TimingTypeDef ComSpaceTiming = {0};
  FMC_NAND_PCC_TimingTypeDef AttSpaceTiming = {0};
  NAND_DeviceConfigTypeDef NAND_DevConfig = {0};

  hnand1.Instance = FMC_NAND_DEVICE;
  /* hnand1.Init */
  hnand1.Init.NandBank = FMC_NAND_BANK3;
  hnand1.Init.Waitfeature = FMC_NAND_WAIT_FEATURE_ENABLE;
  hnand1.Init.MemoryDataWidth = FMC_NAND_MEM_BUS_WIDTH_16;
  hnand1.Init.EccComputation = FMC_NAND_ECC_DISABLE;
  hnand1.Init.ECCPageSize = FMC_NAND_ECC_PAGE_SIZE_256BYTE;
  hnand1.Init.TCLRSetupTime = 0;
  hnand1.Init.TARSetupTime = 2;
  /* ComSpaceTiming */
  ComSpaceTiming.SetupTime = 2;
  ComSpaceTiming.WaitSetupTime = 2;
  ComSpaceTiming.HoldSetupTime = 1;
  ComSpaceTiming.HiZSetupTime = 0;
  /* AttSpaceTiming */
  AttSpaceTiming.SetupTime = 4;
  AttSpaceTiming.WaitSetupTime = 5;
  AttSpaceTiming.HoldSetupTime = 3;
  AttSpaceTiming.HiZSetupTime = 1;

  if (HAL_NAND_Init(&hnand1, &ComSpaceTiming, &AttSpaceTiming) != HAL_OK)
  {
    Error_Handler( );
  }
}



















  NAND_DevConfig.PageSize = 4096;
  NAND_DevConfig.SpareAreaSize = 128;
  NAND_DevConfig.BlockSize = 64;
  NAND_DevConfig.BlockNbr = 2048;
  NAND_DevConfig.PlaneNbr = 1;
  NAND_DevConfig.PlaneSize = 1024;
  NAND_DevConfig.ExtraCommandEnable = DISABLE;

  if (HAL_NAND_ConfigDevice(&hnand, &NAND_DevConfig)!= HAL_OK)
  {
    Error_Handler( );
  }

static void MX_GPIO_Init(void)
{
  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOE_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOG_CLK_ENABLE();
}

static void HAL_FMC_MspInit(void)
{
  GPIO_InitTypeDef GPIO_InitStruct ={0};
  if (FMC_Initialized) {
    return;
  }
  FMC_Initialized = 1;

  /* Peripheral clock enable */
  __HAL_RCC_FMC_CLK_ENABLE();

  GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10
                          |GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14
                          |GPIO_PIN_15;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
  HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

  GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
                          |GPIO_PIN_12|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_0
                          |GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_7;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

  GPIO_InitStruct.Pin = GPIO_PIN_7;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
  HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
}
hal_nand_handle_t *mx_fmc_nand_init(void)
{
  hal_nand_config_t nand_config;
  hal_nand_memory_config_t p_config;
  hal_nand_partition_config_t nand_partition_config;

  if (HAL_NAND_Init(&hNAND, HAL_NAND1) != HAL_OK)
  {
    return NULL;
  }

  nand_config.wait_feature_status = HAL_NAND_WAIT_FEATURE_ENABLED;
  nand_config.ecc_algorithm       = HAL_NAND_ECC_ALGO_NONE;
  nand_config.chunk_size          = HAL_NAND_CHUNK_SIZE_256_BYTE;

  if (HAL_NAND_SetConfig(&hNAND, &nand_config) != HAL_OK)
  {
    return NULL;
  }

  /* Memory configuration */
  p_config.data_width               = HAL_NAND_DATA_BUS_WIDTH_16_BIT;
  p_config.ecc_offset               = 0;
  p_config.extra_command_status     = HAL_NAND_EXTRA_COMMAND_DISABLED;
  p_config.extra_command_timeout_us = 0;
  p_config.program_timeout_us       = 1000;
  p_config.erase_timeout_ms         = 1000;
  p_config.tclr_setup_time_nsec     = 14;
  p_config.tar_setup_time_nsec      = 42;

  p_config.timing.setup_time_ns     = 42;
  p_config.timing.wait_time_ns      = 42;
  p_config.timing.hold_time_ns      = 14;
  p_config.timing.hiz_time_ns       = 14;

  if (HAL_NAND_SetConfigMemory(&hNAND, &p_config) != HAL_OK)
  {
    return NULL;
  }

  attribute_timing.setup_time_ns     = 70;
  attribute_timing.wait_time_ns      = 84;
  attribute_timing.hold_time_ns      = 56;
  attribute_timing.hiz_time_ns       = 14;

  if (HAL_NAND_SetLastWriteAccessTiming(&hnand, &attribute_timing) != HAL_OK)
  {
    return NULL;
  }

  nand_partition_config.page_size_byte = 4096U;
  nand_partition_config.spare_area_size_byte = 128U;
  nand_partition_config.page_nbr_per_block = 64U;
  nand_partition_config.block_nbr= 2048U;
  nand_partition_config.lun_nbr = 1U;



  if (HAL_NAND_SetConfigPartition(&hnand, &nand_partition_config) != HAL_OK)
  {
    return NULL;
  }

  HAL_RCC_GPIOB_EnableClock();
  HAL_RCC_GPIOC_EnableClock();
  HAL_RCC_GPIOE_EnableClock();
  HAL_RCC_GPIOD_EnableClock();
  HAL_RCC_GPIOJ_EnableClock();
  HAL_RCC_GPIOA_EnableClock();
  HAL_RCC_GPIOF_EnableClock();

  hal_gpio_config_t  gpio_config;

  gpio_config.mode        = HAL_GPIO_MODE_ALTERNATE;
  gpio_config.output_type = HAL_GPIO_OUTPUT_PUSHPULL;
  gpio_config.pull        = HAL_GPIO_PULL_NO;
  gpio_config.speed       = HAL_GPIO_SPEED_FREQ_LOW;
  gpio_config.alternate   = HAL_GPIO_AF_12;
  HAL_GPIO_Init(HAL_GPIOB, HAL_GPIO_PIN_14 | HAL_GPIO_PIN_13 | HAL_GPIO_PIN_12 | HAL_GPIO_PIN_11 | HAL_GPIO_PIN_15 | HAL_GPIO_PIN_5 | HAL_GPIO_PIN_4 | HAL_GPIO_PIN_1 | HAL_GPIO_PIN_6 | HAL_GPIO_PIN_7, &gpio_config);
  HAL_GPIO_Init(HAL_GPIOC, HAL_GPIO_PIN_1 | HAL_GPIO_PIN_2 | HAL_GPIO_PIN_3 | HAL_GPIO_PIN_4 | HAL_GPIO_PIN_5 | HAL_GPIO_PIN_7 | HAL_GPIO_PIN_4 | HAL_GPIO_PIN_1 | HAL_GPIO_PIN_2 | HAL_GPIO_PIN_3 | HAL_GPIO_PIN_4 | HAL_GPIO_PIN_5 | HAL_GPIO_PIN_8, &gpio_config);
  HAL_GPIO_Init(HAL_GPIOE, HAL_GPIO_PIN_7 | HAL_GPIO_PIN_5 | HAL_GPIO_PIN_6 | HAL_GPIO_PIN_8 | HAL_GPIO_PIN_11 | HAL_GPIO_PIN_12 | HAL_GPIO_PIN_13, &gpio_config);
  HAL_GPIO_Init(HAL_GPIOJ, HAL_GPIO_PIN_1 | HAL_GPIO_PIN_9 | HAL_GPIO_PIN_10 | HAL_GPIO_PIN_2 | HAL_GPIO_PIN_3 | HAL_GPIO_PIN_4 | HAL_GPIO_PIN_8 | HAL_GPIO_PIN_11, &gpio_config);
  HAL_GPIO_Init(HAL_GPIOA, HAL_GPIO_PIN_11 | HAL_GPIO_PIN_10 | HAL_GPIO_PIN_9 | HAL_GPIO_PIN_0 | HAL_GPIO_PIN_12 | HAL_GPIO_PIN_2 | HAL_GPIO_PIN_1 | HAL_GPIO_PIN_5 | HAL_GPIO_PIN_7 | HAL_GPIO_PIN_12 | HAL_GPIO_PIN_11 | HAL_GPIO_PIN_10 | HAL_GPIO_PIN_9 | HAL_GPIO_PIN_2 | HAL_GPIO_PIN_1 | HAL_GPIO_PIN_0 | HAL_GPIO_PIN_5 | HAL_GPIO_PIN_12 | HAL_GPIO_PIN_11 | HAL_GPIO_PIN_10 | HAL_GPIO_PIN_9 | HAL_GPIO_PIN_2 | HAL_GPIO_PIN_1 | HAL_GPIO_PIN_0, &gpio_config);
  HAL_GPIO_Init(HAL_GPIOD, HAL_GPIO_PIN_3 | HAL_GPIO_PIN_6 | HAL_GPIO_PIN_12 | HAL_GPIO_PIN_12 | HAL_GPIO_PIN_11 | HAL_GPIO_PIN_13 | HAL_GPIO_PIN_14 | HAL_GPIO_PIN_15, &gpio_config);
  HAL_GPIO_Init(HAL_GPIOF, HAL_GPIO_PIN_1, &gpio_config);

  gpio_config.alternate   = HAL_GPIO_AF_10;
  HAL_GPIO_Init(HAL_GPIOD, HAL_GPIO_PIN_8 | HAL_GPIO_PIN_9 | HAL_GPIO_PIN_5 | HAL_GPIO_PIN_8 | HAL_GPIO_PIN_9 | HAL_GPIO_PIN_8 | HAL_GPIO_PIN_9, &gpio_config);
  HAL_GPIO_Init(HAL_GPIOB, HAL_GPIO_PIN_0 | HAL_GPIO_PIN_0 | HAL_GPIO_PIN_0, &gpio_config);
  HAL_GPIO_Init(HAL_GPIOF, HAL_GPIO_PIN_4, &gpio_config);

  gpio_config.alternate   = HAL_GPIO_AF_14;
  HAL_GPIO_Init(HAL_GPIOA, HAL_GPIO_PIN_12 | HAL_GPIO_PIN_12 | HAL_GPIO_PIN_12, &gpio_config);
  HAL_GPIO_Init(HAL_GPIOF, HAL_GPIO_PIN_0 | HAL_GPIO_PIN_2 | HAL_GPIO_PIN_7, &gpio_config);
  HAL_GPIO_Init(HAL_GPIOE, HAL_GPIO_PIN_9 | HAL_GPIO_PIN_10, &gpio_config);

  gpio_config.alternate   = HAL_GPIO_AF_7;
  HAL_GPIO_Init(HAL_GPIOD, HAL_GPIO_PIN_2, &gpio_config);
  HAL_GPIO_Init(HAL_GPIOC, HAL_GPIO_PIN_9, &gpio_config);

  /* The isolation must be removed before using any I/O from PJ[12:0] */
  if (HAL_PWR_EnableVddXSPI2IndependentSupply() != HAL_OK)
  {
    return NULL;
  }


  return &hNAND;
}

Deinitialization sequence

static void HAL_FMC_MspDeInit(void)
{
  if (FMC_DeInitialized) {
    return;
  }

  FMC_DeInitialized = 1;

  /* Peripheral clock enable */
  __HAL_RCC_FMC_CLK_DISABLE();

  HAL_GPIO_DeInit(GPIOE, GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10
                          |GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14
                          |GPIO_PIN_15);

  HAL_GPIO_DeInit(GPIOD, GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
                          |GPIO_PIN_12|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_0
                          |GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_7);

  HAL_GPIO_DeInit(GPIOG, GPIO_PIN_7);
}
void mx_fmc_nand_deinit(void)
{
  /* De-initialize all GPIO pins associated with FMC */
  HAL_GPIO_DeInit(HAL_GPIOB, HAL_GPIO_PIN_0 | HAL_GPIO_PIN_1 | HAL_GPIO_PIN_4 | HAL_GPIO_PIN_5 | HAL_GPIO_PIN_6 | HAL_GPIO_PIN_7 | HAL_GPIO_PIN_11 | HAL_GPIO_PIN_12 | HAL_GPIO_PIN_13 | HAL_GPIO_PIN_14 | HAL_GPIO_PIN_15);

  HAL_GPIO_DeInit(HAL_GPIOC, HAL_GPIO_PIN_1 | HAL_GPIO_PIN_2 | HAL_GPIO_PIN_3 | HAL_GPIO_PIN_4 | HAL_GPIO_PIN_5 | HAL_GPIO_PIN_7 | HAL_GPIO_PIN_8 | HAL_GPIO_PIN_9);

  HAL_GPIO_DeInit(HAL_GPIOE, HAL_GPIO_PIN_5 | HAL_GPIO_PIN_6 | HAL_GPIO_PIN_7 | HAL_GPIO_PIN_8 | HAL_GPIO_PIN_9 | HAL_GPIO_PIN_10 | HAL_GPIO_PIN_11 | HAL_GPIO_PIN_12 | HAL_GPIO_PIN_13);

  HAL_GPIO_DeInit(HAL_GPIOD, HAL_GPIO_PIN_2 | HAL_GPIO_PIN_3 | HAL_GPIO_PIN_5 | HAL_GPIO_PIN_6 | HAL_GPIO_PIN_8 | HAL_GPIO_PIN_9 | HAL_GPIO_PIN_11 | HAL_GPIO_PIN_12 | HAL_GPIO_PIN_13 | HAL_GPIO_PIN_14 | HAL_GPIO_PIN_15);

  HAL_GPIO_DeInit(HAL_GPIOJ, HAL_GPIO_PIN_1 | HAL_GPIO_PIN_2 | HAL_GPIO_PIN_3 | HAL_GPIO_PIN_4 | HAL_GPIO_PIN_8 | HAL_GPIO_PIN_9 | HAL_GPIO_PIN_10 | HAL_GPIO_PIN_11);

  HAL_GPIO_DeInit(HAL_GPIOA, HAL_GPIO_PIN_0 | HAL_GPIO_PIN_1 | HAL_GPIO_PIN_2 | HAL_GPIO_PIN_5 | HAL_GPIO_PIN_7 | HAL_GPIO_PIN_9 | HAL_GPIO_PIN_10 | HAL_GPIO_PIN_11 | HAL_GPIO_PIN_12);

  HAL_GPIO_DeInit(HAL_GPIOF, HAL_GPIO_PIN_0 | HAL_GPIO_PIN_1 | HAL_GPIO_PIN_2 | HAL_GPIO_PIN_4 | HAL_GPIO_PIN_7);

  HAL_NAND_DeInit(&hNAND);
}